हुक्स के साथ रिएक्ट एरर बाउंड्री लागू करना सीखें ताकि रिसोर्स लोडिंग त्रुटियों को संभालकर उपयोगकर्ता अनुभव और ऐप स्थिरता को बेहतर बनाया जा सके।
रिएक्ट में मजबूत रिसोर्स लोडिंग: हुक्स के साथ एरर बाउंड्री में महारत हासिल करना
आधुनिक वेब अनुप्रयोगों में, एसिंक्रोनस रूप से रिसोर्स लोड करना एक आम बात है। चाहे वह एपीआई से डेटा लाना हो, इमेज लोड करना हो, या मॉड्यूल इम्पोर्ट करना हो, रिसोर्स लोडिंग के दौरान संभावित त्रुटियों को संभालना एक सहज उपयोगकर्ता अनुभव के लिए महत्वपूर्ण है। रिएक्ट एरर बाउंड्री अपने चाइल्ड कंपोनेंट ट्री में कहीं भी जावास्क्रिप्ट त्रुटियों को पकड़ने, उन त्रुटियों को लॉग करने और पूरे एप्लिकेशन को क्रैश करने के बजाय एक फॉलबैक यूआई प्रदर्शित करने के लिए एक तंत्र प्रदान करते हैं। यह लेख बताता है कि रिसोर्स लोडिंग त्रुटियों को प्रबंधित करने के लिए रिएक्ट हुक्स के साथ एरर बाउंड्री का प्रभावी ढंग से उपयोग कैसे करें।
एरर बाउंड्री को समझना
रिएक्ट 16 से पहले, कंपोनेंट रेंडरिंग के दौरान अनहैंडल्ड जावास्क्रिप्ट त्रुटियां रिएक्ट की आंतरिक स्थिति को खराब कर देती थीं और बाद के रेंडर पर अस्पष्ट त्रुटियां पैदा करती थीं। एरर बाउंड्री इस समस्या का समाधान करती हैं, क्योंकि वे अपने चाइल्ड कंपोनेंट्स में होने वाली त्रुटियों के लिए कैच-ऑल ब्लॉक के रूप में कार्य करती हैं। वे रिएक्ट कंपोनेंट्स हैं जो निम्नलिखित में से एक या दोनों लाइफसाइकिल मेथड्स को लागू करते हैं:
static getDerivedStateFromError(error): यह स्टैटिक मेथड तब कॉल होता है जब किसी डिसेंडेंट कंपोनेंट द्वारा कोई त्रुटि फेंकी जाती है। यह फेंकी गई त्रुटि को एक आर्ग्यूमेंट के रूप में प्राप्त करता है और कंपोनेंट की स्थिति को अपडेट करने के लिए एक मान लौटाता है।componentDidCatch(error, info): यह लाइफसाइकिल मेथड तब कॉल होता है जब किसी डिसेंडेंट कंपोनेंट द्वारा कोई त्रुटि फेंकी जाती है। यह फेंकी गई त्रुटि को एक आर्ग्यूमेंट के रूप में प्राप्त करता है, साथ ही एक ऑब्जेक्ट जिसमें यह जानकारी होती है कि किस कंपोनेंट ने त्रुटि फेंकी है। आप इसका उपयोग त्रुटि जानकारी लॉग करने के लिए कर सकते हैं।
महत्वपूर्ण रूप से, एरर बाउंड्री केवल रेंडरिंग चरण में, लाइफसाइकिल मेथड्स में, और उनके नीचे के पूरे ट्री के कंस्ट्रक्टर में त्रुटियों को पकड़ती हैं। वे इनके लिए त्रुटियों को नहीं पकड़ती हैं:
- इवेंट हैंडलर (नीचे दिए गए अनुभाग में और जानें)
- एसिंक्रोनस कोड (जैसे,
setTimeoutयाrequestAnimationFrameकॉलबैक) - सर्वर-साइड रेंडरिंग
- एरर बाउंड्री में ही फेंकी गई त्रुटियां (बजाय उसके बच्चों के)
एरर बाउंड्री और रिएक्ट हुक्स: एक शक्तिशाली संयोजन
जबकि एरर बाउंड्री को लागू करने के लिए पारंपरिक रूप से क्लास कंपोनेंट्स का उपयोग किया जाता था, रिएक्ट हुक्स एक अधिक संक्षिप्त और कार्यात्मक दृष्टिकोण प्रदान करते हैं। हम एक पुन: प्रयोज्य useErrorBoundary हुक बना सकते हैं जो एरर हैंडलिंग लॉजिक को एनकैप्सुलेट करता है और उन कंपोनेंट्स को रैप करने का एक सुविधाजनक तरीका प्रदान करता है जो रिसोर्स लोडिंग के दौरान त्रुटियां फेंक सकते हैं।
एक कस्टम useErrorBoundary हुक बनाना
यहां एक useErrorBoundary हुक का एक उदाहरण है:
import { useState, useCallback } from 'react';
function useErrorBoundary() {
const [error, setError] = useState(null);
const resetError = useCallback(() => {
setError(null);
}, []);
const captureError = useCallback((e) => {
setError(e);
}, []);
const ErrorBoundary = useCallback(({ children, fallback }) => {
if (error) {
return fallback ? fallback : An error occurred: {error.message || String(error)};
}
return children;
}, [error]);
return { ErrorBoundary, captureError, error, resetError };
}
export default useErrorBoundary;
स्पष्टीकरण:
useState: हम त्रुटि स्थिति को प्रबंधित करने के लिएuseStateका उपयोग करते हैं। यह शुरू में त्रुटि कोnullपर सेट करता है।useCallback: हमresetErrorऔरcaptureErrorफ़ंक्शंस को मेमोइज़ करने के लिएuseCallbackका उपयोग करते हैं। यदि इन फ़ंक्शंस को प्रॉप्स के रूप में नीचे पास किया जाता है तो अनावश्यक री-रेंडर को रोकने के लिए यह एक अच्छी प्रैक्टिस है।ErrorBoundaryकंपोनेंट: यहuseCallbackके साथ बनाया गया एक फंक्शनल कंपोनेंट है जोchildrenऔर एक वैकल्पिकfallbackप्रॉप लेता है। यदि स्थिति में कोई त्रुटि मौजूद है, तो यह या तो प्रदान किए गएfallbackकंपोनेंट को या एक डिफ़ॉल्ट त्रुटि संदेश को रेंडर करता है। अन्यथा, यह बच्चों को रेंडर करता है। यह हमारी एरर बाउंड्री के रूप में कार्य करता है। डिपेंडेंसी ऐरे `[error]` यह सुनिश्चित करती है कि `error` स्थिति बदलने पर यह फिर से रेंडर हो।captureErrorफ़ंक्शन: इस फ़ंक्शन का उपयोग त्रुटि स्थिति को सेट करने के लिए किया जाता है। आप इसे रिसोर्स लोड करते समयtry...catchब्लॉक के भीतर कॉल करेंगे।resetErrorफ़ंक्शन: यह फ़ंक्शन त्रुटि स्थिति को साफ़ करता है, जिससे कंपोनेंट अपने बच्चों को फिर से रेंडर कर सकता है (संभावित रूप से रिसोर्स लोडिंग का पुनः प्रयास कर सकता है)।
एरर हैंडलिंग के साथ रिसोर्स लोडिंग को लागू करना
अब, आइए देखें कि रिसोर्स लोडिंग त्रुटियों को संभालने के लिए इस हुक का उपयोग कैसे करें। एक ऐसे कंपोनेंट पर विचार करें जो एक एपीआई से उपयोगकर्ता डेटा प्राप्त करता है:
import React, { useState, useEffect } from 'react';
import useErrorBoundary from './useErrorBoundary';
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const { ErrorBoundary, captureError, error, resetError } = useErrorBoundary();
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch(`https://api.example.com/users/${userId}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
setUser(data);
} catch (e) {
captureError(e);
}
};
fetchData();
}, [userId, captureError]);
if (error) {
return (
Failed to load user data. {user.name}
Email: {user.email}
{/* Other user details */}स्पष्टीकरण:
- हम
useErrorBoundaryहुक इम्पोर्ट करते हैं। - हम
ErrorBoundaryकंपोनेंट,captureErrorफ़ंक्शन,errorस्थिति, औरresetErrorफ़ंक्शन प्राप्त करने के लिए हुक को कॉल करते हैं। useEffectहुक के अंदर, हम एपीआई कॉल कोtry...catchब्लॉक में रैप करते हैं।- यदि एपीआई कॉल के दौरान कोई त्रुटि होती है, तो हम त्रुटि स्थिति को सेट करने के लिए
captureError(e)को कॉल करते हैं। - यदि
errorस्थिति सेट है, तो हमErrorBoundaryकंपोनेंट को रेंडर करते हैं। हम एक कस्टमfallbackप्रॉप प्रदान करते हैं जो एक त्रुटि संदेश और एक "पुनः प्रयास करें" (Retry) बटन प्रदर्शित करता है। बटन पर क्लिक करने से त्रुटि स्थिति को साफ़ करने के लिएresetErrorकॉल होता है, जिससे एक री-रेंडर और डेटा प्राप्त करने का एक और प्रयास होता है। - यदि कोई त्रुटि नहीं हुई है और उपयोगकर्ता डेटा लोड हो गया है, तो हम उपयोगकर्ता प्रोफ़ाइल विवरण रेंडर करते हैं।
विभिन्न प्रकार की रिसोर्स लोडिंग त्रुटियों को संभालना
विभिन्न प्रकार की रिसोर्स लोडिंग त्रुटियों के लिए अलग-अलग हैंडलिंग रणनीतियों की आवश्यकता हो सकती है। यहां कुछ सामान्य परिदृश्य और उन्हें संबोधित करने के तरीके दिए गए हैं:
नेटवर्क त्रुटियां
नेटवर्क त्रुटियां तब होती हैं जब क्लाइंट सर्वर से कनेक्ट करने में असमर्थ होता है (उदाहरण के लिए, नेटवर्क आउटेज या सर्वर डाउनटाइम के कारण)। उपरोक्त उदाहरण पहले से ही `response.ok` का उपयोग करके बुनियादी नेटवर्क त्रुटियों को संभालता है। आप और अधिक परिष्कृत त्रुटि का पता लगाना जोड़ना चाह सकते हैं, उदाहरण के लिए:
//Inside the fetchData function
try {
const response = await fetch(`https://api.example.com/users/${userId}`);
if (!response.ok) {
// Consider adding specific error code handling
if (response.status === 404) {
throw new Error("User not found");
} else if (response.status >= 500) {
throw new Error("Server error. Please try again later.");
} else {
throw new Error(`HTTP error! status: ${response.status}`);
}
}
const data = await response.json();
setUser(data);
} catch (error) {
if (error.message === 'Failed to fetch') {
// Likely a network error
captureError(new Error('Network error. Please check your internet connection.'));
} else {
captureError(error);
}
}
इस मामले में, आप उपयोगकर्ता को एक संदेश प्रदर्शित कर सकते हैं जो यह दर्शाता है कि नेटवर्क कनेक्टिविटी की समस्या है और उन्हें अपने इंटरनेट कनेक्शन की जांच करने का सुझाव दे सकते हैं।
एपीआई त्रुटियां
एपीआई त्रुटियां तब होती हैं जब सर्वर एक त्रुटि प्रतिक्रिया देता है (उदाहरण के लिए, एक 400 Bad Request या 500 Internal Server Error)। जैसा कि ऊपर दिखाया गया है, आप `response.status` की जांच कर सकते हैं और इन त्रुटियों को उचित रूप से संभाल सकते हैं।
डेटा पार्सिंग त्रुटियां
डेटा पार्सिंग त्रुटियां तब होती हैं जब सर्वर से प्रतिक्रिया अपेक्षित प्रारूप में नहीं होती है और इसे पार्स नहीं किया जा सकता है (उदाहरण के लिए, अमान्य JSON)। आप इन त्रुटियों को response.json() कॉल को try...catch ब्लॉक में रैप करके संभाल सकते हैं:
//Inside the fetchData function
try {
const response = await fetch(`https://api.example.com/users/${userId}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
setUser(data);
} catch (error) {
if (error instanceof SyntaxError) {
captureError(new Error('Failed to parse data from server.'));
} else {
captureError(error);
}
}
इमेज लोडिंग त्रुटियां
इमेज लोडिंग के लिए, आप <img> टैग पर onError इवेंट हैंडलर का उपयोग कर सकते हैं:
function MyImage({ src, alt }) {
const { ErrorBoundary, captureError } = useErrorBoundary();
const [imageLoaded, setImageLoaded] = useState(false);
const handleImageLoad = () => {
setImageLoaded(true);
};
const handleImageError = (e) => {
captureError(new Error(`Failed to load image: ${src}`));
};
return (
Failed to load image.